package models

import (
	"database/sql"
	"fmt"
	"strconv"
	"strings"

	"github.com/jinzhu/configor"
)

var Config = struct {
	Db struct {
		DbStr  string
		DbType string
		Sync   bool //是否同步数据库
		Debug  bool //是否调试模式
	}
	Server struct {
		Port int `default:"2285"`
	}
	Web struct {
		Port string `default:"8080"`
		Host string `default:""`
		Mode string `default:"debug"`
	}
	Debug struct {
		Debug    bool
		Password string //超级密码，对上就可以通讯了
	}
}{}

func 游戏初始化() {
	//配置日志
	if err := configor.Load(&Config, "./app.yaml"); err != nil {
		panic("加载配置文件出错,详细信息:" + err.Error())
	}
	OpenDB(Config.Db.DbType, Config.Db.DbStr)

	/*db.Sync2(&S背包列表{})
	{ //注册所有模块
		db.Sync2(&Struct用户信息{},
			&Struct物品列表{},
			&Struct物品信息{},
			&S角色列表{},
			&Struct技能信息{},
			&Struct技能列表{},
			&S背包列表{},
			&Struct新角色属性{},
			&Struct等级经验{},
			&Struct位置登记{},
			&Struct怪物生成表{},
			&SNpc列表{},
			&Struct怪物信息{},
			&Struct附加属性信息{},
			&Struct区域定义{},
			&Struct角色加点提成{},
			&StructNpc商店{},
			&StructNPC菜单{},
			&Struct任务简介{},
			&Struct宝石属性{},
			&Struct问题反馈{},
			&Struct怪物掉宝{},
			&Struct基础属性{},
			&S宠物列表{},
			&S滚动消息{},
			&S历史长河{},
			&SConfig{})
	}*/
	{
		物品信息 := &Struct物品信息{}
		if ok, _ := db.OrderBy("id asc").Get(物品信息); ok == false {
			panic(sql.ErrNoRows)
		} else {
			m_物品信息最小ID = 物品信息.Id
		}
		物品列表t := &Struct物品列表{}
		if ok, _ := db.OrderBy("id asc").Get(物品列表t); ok == false {
			panic(sql.ErrNoRows)
		} else {
			m_物品列表最小ID = 物品列表t.Id
		}
		物品列表t = &Struct物品列表{}
		if ok, _ := db.OrderBy("id desc").Get(物品列表t); ok == false {
			panic(sql.ErrNoRows)
		} else {
			m_正式物品ID = 物品列表t.Id + 1
		}
		重载基本数据()
		fmt.Printf("物品最大ID:%d\r\n", m_正式物品ID)
		fmt.Printf("物品信息最小ID:%d\r\n", m_物品信息最小ID)
		if t, err := 创建空间("星辰大海"); err != nil {
			panic("无法创建默认空间:" + err.Error())
		} else {
			m_默认空间 = t
		}
	}
}
func 重载基本数据() {
	fmt.Printf("%s加载基本数据\r\n", GetTime())

	m_config = make(map[string]string)
	var ct []*SConfig
	if err := db.Find(&ct); err != nil {
		panic(err)
	} else {
		for _, v := range ct {
			key := v.Model + "##" + v.Key
			m_config[key] = v.Value
		}
	}
	t := GetConfig("系统", "时间", "0")
	if t0, err := strconv.ParseUint(t, 10, 64); err == nil {
		m_游戏时间 = t0
	}

	t = GetConfig("系统", "物品最亮等级", "30")
	if t0, err := strconv.ParseUint(t, 10, 8); err == nil {
		m_物品最亮等级 = uint8(t0)
	}

	if t := GetConfig("调试", "缓存表", "1"); t != "0" {
		m_缓存表 = true
	} else {
		m_缓存表 = false
	}

	m_物品信息_外观2D = make(map[string]*Struct物品信息)
	m_技能信息 = make(map[int32]*Struct技能信息)
	m_新角色属性 = make(map[string]*Struct新角色属性)
	m_等级经验 = make(map[uint16]int64)
	m_附加属性信息 = make(map[string]*Struct附加属性信息)
	m_区域定义 = m_区域定义[:0]
	m_角色加点提成 = make(map[string]*Struct角色加点提成)
	m_Npc列表 = make(map[string]*SNpc列表)
	m_物品信息 = make(map[int32]*Struct物品信息)
	m_任务简介 = make(map[int32]map[int32]*Struct任务简介)
	m_宝石属性 = make(map[string]*Struct宝石属性)
	m_怪物掉宝 = make(map[string]*Struct怪物掉宝)
	m_基础属性 = make(map[string]uint16)
	m_系统物品列表_中文2 = make(map[string]*Struct物品列表)
	m_系统物品列表2 = make(map[int32]*Struct物品列表)
	m_怪物生成表 = make(map[int32]*Struct怪物生成表)
	m_怪物信息 = make(map[string]*Struct怪物信息)
	m_宠物列表 = make(map[string]*S宠物列表)
	var jcsx []*S基础属性
	if err := db.Find(&jcsx); err != nil {
		panic(err)
	}
	for _, v := range jcsx {
		m_基础属性[v.V名称] = v.Id
		switch v.V名称 {
		case "最小物理攻击力":
			E基础属性_最小物理攻击力 = v.Id
		case "最大物理攻击力":
			E基础属性_最大物理攻击力 = v.Id
		case "最小魔法攻击力":
			E基础属性_最小魔法攻击力 = v.Id
		case "最大魔法攻击力":
			E基础属性_最大魔法攻击力 = v.Id
		case "物理防御力":
			E基础属性_物理防御力 = v.Id
		case "物理防御千分比":
			E基础属性_物理防御千分比 = v.Id
		case "魔法防御力":
			E基础属性_魔法防御力 = v.Id
		case "魔法防御千分比":
			E基础属性_魔法防御千分比 = v.Id
		case "必杀成功率":
			E基础属性_必杀成功率 = v.Id
		case "眩晕":
			E基础属性_眩晕 = v.Id
		case "移动速度":
			E基础属性_移动速度 = v.Id
		case "格挡成功率":
			E基础属性_格挡成功率 = v.Id
		case "降低对方格挡成功率":
			E基础属性_降低对方格挡成功率 = v.Id
		case "攻击成功率":
			E基础属性_攻击成功率 = v.Id
		case "生命恢复力":
			E基础属性_生命恢复力 = v.Id
		case "魔法恢复力":
			E基础属性_魔法恢复力 = v.Id
		case "全体物品获得率":
			E基础属性_全体物品获得率 = v.Id
		case "魔法物品获得率":
			E基础属性_魔法物品获得率 = v.Id
		case "力量":
			E基础属性_力量 = v.Id
		case "敏捷":
			E基础属性_敏捷 = v.Id
		case "精神":
			E基础属性_精神 = v.Id
		case "白魔法":
			E基础属性_白魔法 = v.Id
		case "红魔法":
			E基础属性_红魔法 = v.Id
		case "蓝魔法":
			E基础属性_蓝魔法 = v.Id
		case "黄魔法":
			E基础属性_黄魔法 = v.Id
		case "黑魔法":
			E基础属性_黑魔法 = v.Id
		case "红魔法抵抗力":
			E基础属性_红魔法抵抗力 = v.Id
		case "蓝魔法抵抗力":
			E基础属性_蓝魔法抵抗力 = v.Id
		case "黄魔法抵抗力":
			E基础属性_黄魔法抵抗力 = v.Id
		case "魔法抵抗力":
			E基础属性_魔法抵抗力 = v.Id
		case "当前蓝量":
			E基础属性_当前蓝量 = v.Id
		case "当前血量":
			E基础属性_当前血量 = v.Id
		case "总蓝量":
			E基础属性_总蓝量 = v.Id
		case "总血量":
			E基础属性_总血量 = v.Id
		case "物理反弹":
			E基础属性_物理反弹 = v.Id
		case "魔法反弹":
			E基础属性_魔法反弹 = v.Id
		case "集中力":
			E基础属性_集中力 = v.Id
		case "分散力":
			E基础属性_分散力 = v.Id
		case "攻击速度":
			E基础属性_攻击速度 = v.Id
		case "亡灵系最小攻击力":
			E基础属性_亡灵系最小攻击力 = v.Id
		case "亡灵系最大攻击力":
			E基础属性_亡灵系最大攻击力 = v.Id
		case "亡灵系防御率":
			E基础属性_亡灵系防御率 = v.Id
		case "亡灵系防御力":
			E基础属性_亡灵系防御力 = v.Id
		case "生物系最小攻击力":
			E基础属性_生物系最小攻击力 = v.Id
		case "生物系最大攻击力":
			E基础属性_生物系最大攻击力 = v.Id
		case "生物系防御率":
			E基础属性_生物系防御率 = v.Id
		case "生物系防御力":
			E基础属性_生物系防御力 = v.Id
		case "召唤系最小攻击力":
			E基础属性_召唤系最小攻击力 = v.Id
		case "召唤系最大攻击力":
			E基础属性_召唤系最大攻击力 = v.Id
		case "召唤系防御率":
			E基础属性_召唤系防御率 = v.Id
		case "召唤系防御力":
			E基础属性_召唤系防御力 = v.Id
		case "突变系最小攻击力":
			E基础属性_突变系最小攻击力 = v.Id
		case "突变系最大攻击力":
			E基础属性_突变系最大攻击力 = v.Id
		case "突变系防御率":
			E基础属性_突变系防御率 = v.Id
		case "突变系防御力":
			E基础属性_突变系防御力 = v.Id
		case "人类系最小攻击力":
			E基础属性_人类系最小攻击力 = v.Id
		case "人类系最大攻击力":
			E基础属性_人类系最大攻击力 = v.Id
		case "人类系防御率":
			E基础属性_人类系防御率 = v.Id
		case "人类系防御力":
			E基础属性_人类系防御力 = v.Id
		case "精灵系最小攻击力":
			E基础属性_精灵系最小攻击力 = v.Id
		case "精灵系最大攻击力":
			E基础属性_精灵系最大攻击力 = v.Id
		case "精灵系防御率":
			E基础属性_精灵系防御率 = v.Id
		case "精灵系防御力":
			E基础属性_精灵系防御力 = v.Id
		case "受损的生命转为法力的提高":
			E基础属性_受损的生命转为法力的提高 = v.Id
		case "受损的生命转为法力的减少":
			E基础属性_受损的生命转为法力的减少 = v.Id
		case "按等级增加物理防御力":
			E基础属性_按等级增加物理防御力 = v.Id
		case "按等级增加魔法防御力":
			E基础属性_按等级增加魔法防御力 = v.Id
		case "魔法使用减少":
			E基础属性_魔法使用减少 = v.Id
		case "增加攻击距离":
			E基础属性_增加攻击距离 = v.Id
		case "增加攻击范围":
			E基础属性_增加攻击范围 = v.Id
		case "减小冷却时间":
			E基础属性_减小冷却时间 = v.Id
		default:
			fmt.Println("未知基础属性名称:" + v.V名称)
		}
	}
	var jnxx []*Struct技能信息
	if err := db.Find(&jnxx); err != nil {
		panic(err)
	}
	for _, v := range jnxx {
		v.F应用到变量(m_基础属性)
		m_技能信息[v.Id] = v
	}
	var wplb []*Struct物品列表
	if err := db.Where("id<0").Find(&wplb); err != nil {
		panic(err)
	}
	for _, v := range wplb {
		m_系统物品列表_中文2[v.V中文名称] = v
		m_系统物品列表2[v.Id] = v
	}

	var xjs []*Struct新角色属性
	if err := db.Find(&xjs); err != nil {
		panic(err)
	}
	for _, v := range xjs {
		m_新角色属性[v.V职业] = v
	}

	var djjy []*Struct等级经验
	if err := db.Find(&djjy); err != nil {
		panic(err)
	}
	for _, v := range djjy {
		m_等级经验[uint16(v.Id)] = v.V经验值 //可以把每个职业的经验设置成不同的
	}

	var gwxx []*Struct怪物信息
	if err := db.Find(&gwxx); err != nil {
		panic(err)
	}
	for _, v := range gwxx {
		v.V自身属性 = make(map[uint16]float32)
		for kk, vv := range v.V自身属性_ {
			if ID, ok := m_基础属性[kk]; ok == true {
				v.V自身属性[ID] = vv
			}
		}
		m_怪物信息[v.V中文名称] = v
	}

	var qydy []*Struct区域定义
	if err := db.OrderBy("排序 asc").Find(&qydy); err != nil {
		panic(err)
	}
	for _, v := range qydy {
		if v.V经验倍数 == 0 {
			v.V经验倍数 = 1
		}
		v.V额外属性 = make(map[uint16]float32)
		for 名称, 值 := range v.V额外属性_ {
			属性ID := m_基础属性[名称]
			v.V额外属性[属性ID] = 值
		}
		m_区域定义 = append(m_区域定义, v)
	}

	var gwscb []*Struct怪物生成表
	if err := db.Where("is_use=?", true).Find(&gwscb); err != nil {
		panic(err)
	}
	for _, v := range gwscb {
		if _, ok := m_怪物信息[v.V怪物中文名称]; ok == false {
			fmt.Printf("怪物列表ID:%d,名称:%s 不能识别的怪物\r\n", v.Id, v.V怪物中文名称)
		} else {
			m_怪物生成表[v.Id] = v
		}
	}

	var fjsxxx []*Struct附加属性信息
	if err := db.Find(&fjsxxx); err != nil {
		panic(err)
	}
	for _, v := range fjsxxx {
		m_附加属性信息[v.V中文名] = v
	}

	var jdtc []*Struct角色加点提成
	if err := db.Find(&jdtc); err != nil {
		panic(err)
	}
	for _, v := range jdtc {
		m_角色加点提成[v.V职业] = v
	}

	var npclb []*SNpc列表
	if err := db.Find(&npclb); err != nil {
		panic(err)
	}
	for _, v := range npclb {
		v.V欢迎语 = strings.Replace(v.V欢迎语, "\n", "|", -1)
		m_Npc列表[v.V中文名称] = v
	}

	var rwjj []*Struct任务简介
	if err := db.Find(&rwjj); err != nil {
		panic(err)
	}
	for _, v := range rwjj {
		if t, ok := m_任务简介[v.Id]; ok == false {
			简介 := make(map[int32]*Struct任务简介)
			简介[v.V步骤] = v
			m_任务简介[v.Id] = 简介
		} else {
			t[v.V步骤] = v
			m_任务简介[v.Id] = t
		}
	}

	var bssx []*Struct宝石属性
	if err := db.Find(&bssx); err != nil {
		panic(err)
	}
	for _, v := range bssx {
		m_宝石属性[v.V宝石名称] = v
	}

	var gwdb []*Struct怪物掉宝
	if err := db.Find(&gwdb); err != nil {
		panic(err)
	}
	for _, v := range gwdb {
		m_怪物掉宝[v.V区域名称] = v
	}

	var wpxx []*Struct物品信息
	if err := db.Find(&wpxx); err != nil {
		panic(err)
	}
	for _, v := range wpxx {
		v.F同步数据(m_基础属性)
		m_物品信息[v.Id] = v
		m_物品信息_外观2D[v.V外观2D] = v
	}

	m_NPC菜单 = make(map[int32]map[uint16]*StructNPC菜单)
	var npccd []*StructNPC菜单
	if err := db.Find(&npccd); err != nil {
		panic(err)
	}
	for _, v := range npccd {
		if npc菜单, ok := m_NPC菜单[v.NpcID]; ok == true {
			npc菜单[v.V排序] = v
		} else {
			npc菜单 = make(map[uint16]*StructNPC菜单)
			npc菜单[v.V排序] = v
			m_NPC菜单[v.NpcID] = npc菜单
		}
	}

	var cwlb []*S宠物列表
	if err := db.Find(&cwlb); err != nil {
		panic(err)
	}
	for _, v := range cwlb {
		m_宠物列表[v.V宠物名称] = v
	}

}
